package com.example.socket.executor;

import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.concurrent.Promise;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;

public class SingleThreadExecutor implements Executor {
	private final Promise<?> terminationFuture = new DefaultPromise<Void>(
			GlobalEventExecutor.INSTANCE);

	private final ThreadFactory factory;

	private volatile Thread thread;

	public SingleThreadExecutor(ThreadFactory factory) {
		this.factory = factory;
	}

	@Override
	public void execute(final Runnable command) {
		if (null == thread) {
			thread = factory.newThread(new Runnable() {
				@Override
				public void run() {
					try {
						command.run();
					} finally {
						terminationFuture.setSuccess(null);
					}
				}
			});
		}
		if (null == thread) {
			throw new RuntimeException("Failed to create thread to run: "
					+ command);
		}
		thread.start();
	}

	public Thread getThread() {
		return thread;
	}

	public Promise<?> getTerminationFuture() {
		return terminationFuture;
	}
}
